package com.yc.clouduser.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yc.clouduser.entity.User;
import com.yc.clouduser.mapper.UserMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

@Component
@ServerEndpoint("/says/{id}/{cid}")
@Slf4j
public class MyWebSocket {


    //存储用户会话
    public static UserMapper userMapper;

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        MyWebSocket.userMapper = userMapper;
    }
    static HashSet<Session> sessions = new HashSet<>();


    //连接
    @OnOpen
    public void onOpen(Session session, @PathParam("id") String id, @PathParam("cid") String cid) throws IOException {
        log.info(id + "上线了！");
        //在会话中存入id
        User user = userMapper.selectById(id);

        //存取用户所需信息
        MyInfo myInfo = new MyInfo();
        myInfo.setId(user.getId());
        myInfo.setPic(user.getPic());
        myInfo.setCid(cid);

        session.getUserProperties().put("myInfo", myInfo);
        sessions.add(session);
        send(new MsgInfo(sessions.stream().map(s->(MyInfo)s.getUserProperties().get("myInfo")).collect(Collectors.toList()),
                myInfo, ""));
    }

    //关闭
    @OnClose
    public void onClose(Session session) throws IOException {
        //取
        MyInfo myInfo = (MyInfo) session.getUserProperties().get("myInfo");
        String cid = String.valueOf(myInfo.getCid());
        log.info(myInfo.getId() + "下线了！");
        sessions.remove(session);
        send(new MsgInfo(sessions.stream().map(s->(MyInfo)s.getUserProperties().get("myInfo")).collect(Collectors.toList()),
                myInfo, ""));
    }

    //消息提示
    @OnMessage
    public void onMessage(Session session, String message) throws IOException {
        MyInfo myInfo = (MyInfo) session.getUserProperties().get("myInfo");

        //解析消息
        ObjectMapper objectMapper = new ObjectMapper();
        wssay say;
        try {
            say = objectMapper.readValue(message, wssay.class);
        } catch (Exception e) {
            // 处理解析错误
            log.error("Failed to parse message: " + message, e);
            return;
        }


        if("say".equals(say.getType())){
            log.info(myInfo.getId() + "说：" + say.getMsg());
            //消息发送
            send(new MsgInfo(null,
                    myInfo, say.getMsg()));
        }else if("change class".equals(say.getType())){
            //切换班级
            myInfo.setCid(say.getMsg());
            //发送请求
            send(new MsgInfo(sessions.stream().map(s->(MyInfo)s.getUserProperties().get("myInfo")).collect(Collectors.toList()),
                    myInfo, ""));
            log.info(myInfo.getId() + "切换班级：" + say.getMsg());
        } else if ("updateClassName".equals(say.getType())) {
            //接收信息
            log.info(myInfo.getId() + "重新查询：" + say.getMsg());
            sendUpdate(new MsgInfo(null, null, say.getMsg()));
        } else if ("examination".equals(say.getType())) {
            log.info(myInfo.getId() + "发起考试：" + say.getMsg());
            //消息发送
            send(new MsgInfo(null,
                    myInfo, "examination: " + say.getMsg()));
        }
    }

    //发送方法
    public void send(MsgInfo msgInfo) throws IOException {
        for (Session s : sessions) {
            //将msgInfo转换成json
            MyInfo myInfo = (MyInfo) s.getUserProperties().get("myInfo");
            if(myInfo.getCid().equals(msgInfo.myInfo.getCid())){
                String message = new ObjectMapper().writeValueAsString(msgInfo);
                s.getBasicRemote().sendText(message);
            }
        }
    }

    //发送修改方法
    public void sendUpdate(MsgInfo msgInfo) throws IOException {
        for (Session s : sessions) {
            MyInfo myInfo = (MyInfo) s.getUserProperties().get("myInfo");
            if(myInfo.getCid().equals(msgInfo.getMessage())){
                //将msgInfo转换成json
                String message = new ObjectMapper().writeValueAsString(msgInfo);
                s.getBasicRemote().sendText(message);
            }
        }
    }
}

//发送用户信息
@Data
@AllArgsConstructor
@NoArgsConstructor
class MsgInfo{

    //在线用户列表
    List<MyInfo> onlines;

    //发送人
    MyInfo myInfo;

    //文字消息
    String message;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class MyInfo{
    Integer id;  //用户id
    String cid; //班级id
    String pic; //用户头像
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class wssay {
    private String type;
    private String msg;
}